<template>
  <div class="map-container">
    <div ref="chartRef" class="map"></div>
    <div ref="barRef" class="bar-chart"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import * as echarts from "echarts";
import chinaMapData from "@/assets/json/china.json"; // 引入中国地图数据

const chartRef = ref<HTMLElement | null>(null);
const barRef = ref<HTMLElement | null>(null);

onMounted(() => {
  // 初始化 ECharts 实例
  const myChart = echarts.init(chartRef.value!);
  const barChart = echarts.init(barRef.value!);

  // 注册中国地图
  echarts.registerMap("china", chinaMapData);

  // 地图数据
  const outname = [
    "南海诸岛",
    "北京",
    "天津",
    "上海",
    "重庆",
    "河北",
    "河南",
    "云南",
    "辽宁",
    "黑龙江",
    "湖南",
    "安徽",
    "山东",
    "新疆",
    "江苏",
    "浙江",
    "江西",
    "湖北",
    "广西",
    "甘肃",
    "山西",
    "内蒙古",
    "陕西",
    "吉林",
    "福建",
    "贵州",
    "广东",
    "青海",
    "西藏",
    "四川",
    "宁夏",
    "海南",
    "台湾",
    "香港",
    "澳门",
  ];
  const outvalue = [
    0, 524, 13, 140, 75, 13, 83, 11, 19, 15, 69, 260, 39, 4, 31, 104, 36, 1052, 33, 347, 9, 157, 22, 4, 18, 5, 2398, 41, 0, 484, 404, 22, 3, 5, 225,
  ];
  const outdata = outname.map((name, index) => ({
    name,
    value: outvalue[index],
  }));

  // 获取地图数据
  const geoCoordMap: { [key: string]: number[] } = {};
  const mapFeatures = echarts.getMap("china").geoJson.features;
  mapFeatures.forEach((v) => {
    const name = v.properties.name;
    if (v.properties.center) {
      geoCoordMap[name] = v.properties.center;
    }
  });

  const convertData = (data: { name: string; value: number }[]) => {
    return data
        .map((item) => {
          const geoCoord = geoCoordMap[item.name];
          if (geoCoord) {
            return {
              name: item.name,
              value: [...geoCoord, item.value],
            };
          }
          return null;
        })
        .filter((item): item is { name: string; value: number[] } => item !== null);
  };

  const convertedData = convertData(outdata);

  const option = {
    backgroundColor: "#ffffff",
    tooltip: {
      show: true,
      formatter: function (params) {
        if (params.value.length > 1) {
          return `&nbsp;&nbsp;${params.name}&nbsp;&nbsp;&nbsp;${params.value[2]}人&nbsp;&nbsp;`;
        } else {
          return `&nbsp;&nbsp;${params.name}&nbsp;&nbsp;&nbsp;${params.value}人&nbsp;&nbsp;`;
        }
      },
    },
    geo: {
      map: "china",
      show: true,
      roam: false,
      zoom: 1.7,
      top: 120,
      left: '18%',
      label: {
        emphasis: {
          show: false,
        },
      },
      itemStyle: {
        normal: {
          areaColor: '#C9E6FF',
          borderColor: '#fff',
          borderWidth: 2,
          shadowColor: '#5AB2FE',
          shadowBlur: 20
        }
      },
    },
    series: [
      {
        type: "map",
        map: "china",
        aspectScale: 0.75,
        top: 120,
        left: '18%',
        zoom: 1.7,
        label: {
          normal: {
            show: false,
          },
          emphasis: {
            show: false,
          },
        },
        itemStyle: {
          normal: {
            areaColor: 'transparent',
            borderColor: '#fff',
            borderWidth: 1
          },
          emphasis: {
            areaColor: '#C9E6FF',
            shadowColor: '#5AB2FE',
            shadowBlur: 10
          }
        },
        data: outdata,
      },
      {
        type: "effectScatter",
        coordinateSystem: "geo",
        rippleEffect: {
          brushType: "stroke",
        },
        showEffectOn: "render",
        itemStyle: {
          normal: {
            color: {
              type: "radial",
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [
                {
                  offset: 0,
                  color: "rgba(5,80,151,0.2)",
                },
                {
                  offset: 0.8,
                  color: "rgba(5,80,151,0.8)",
                },
                {
                  offset: 1,
                  color: "rgba(0,108,255,0.7)",
                },
              ],
              global: false,
            },
          },
        },
        label: {
          normal: {
            show: true,
            color: "#fff",
            fontWeight: "bold",
            position: "inside",
            formatter: function (para) {
              return `{cnNum|${para.data.value[2]}}`;
            },
            rich: {
              cnNum: {
                fontSize: 13,
                color: "#D4EEFF",
              },
            },
          },
        },
        symbol: "circle",
        symbolSize: function (val) {
          const max = 6000;
          const min = 10;
          const maxSize4Pin = 100;
          const minSize4Pin = 20;
          if (val[2] === 0) {
            return 0;
          }
          const a = (maxSize4Pin - minSize4Pin) / (max - min);
          const b = maxSize4Pin - a * max;
          return a * val[2] + b * 1.2;
        },
        data: convertedData,
        zlevel: 1,
      },
    ],
  };

  // 设置地图图表选项
  myChart.setOption(option);

  // 计算 Top 10 数据
  const top10Data = outdata
      .filter(item => item.value > 0) // 过滤掉值为 0 的数据
      .sort((a, b) => a.value - b.value) // 按值降序排序
      .slice(-10); // 取前 10 个

  const barOption = {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b} : {c}'
    },
    grid: {
      right: '11%',
      bottom: '2%',
      containLabel: true
    },
    xAxis: {
      type: 'value',
      boundaryGap: [0, 0.01],
      show: false
    },
    yAxis: {
      type: 'category',
      data: top10Data.map(item => item.name),
    },
    series: [
      {
        name: 'Top 10',
        type: 'bar',
        data: top10Data.map(item => item.value),
        label: {
          show: true,
          position: 'right'
        },
        itemStyle: {
          color: '#5AB2FE',
          barBorderRadius: [0, 10, 10, 0]
        }
      }
    ]
  };

  // 设置柱状图选项
  barChart.setOption(barOption);
});
</script>

<style scoped lang="scss">
.map-container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #ffffff;

  .map {
    width: 70%;
    height: 389px;
  }

  .bar-chart {
    width: 30%;
    height: 389px;
  }
}
</style>